package org.report4service.views;

import java.util.Date;

import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Graphics;

import org.report4service.listeners.AlertMessageListener;
import org.report4service.listeners.LogonListner;
import org.report4service.model.Report;
import org.report4service.services.ReportServiceImpl;
import org.report4service.services.UserServiceImpl;
import org.report4service.utils.AlertMessage;
import org.report4service.utils.CalenderUtil;
import org.report4service.utils.CommandPool;
import org.report4service.utils.TextPool;

/**
 * Calendar form.
 * 
 * @author Jmpango
 * 
 */
public class CalenderForm extends Canvas implements CommandListener, AlertMessageListener {

    private CalenderUtil calendarUtil;
    /** Reference to display instance */
    private Display display;
    /** Reference to previous form */
    private Displayable prvScreen;
    /** Reference to application title */
    private String title;
    /** Reference to application logon listener */
    private LogonListner logonListner;
    /** Display alerts */
    private AlertMessage alertMessage;
    /** Reference to the login service */
    private UserServiceImpl userService;
    /** Reference to the report service. */
    private ReportServiceImpl reportService;

    public CalenderForm(Display display, Displayable prvScreen, String title,
            LogonListner logonListner, UserServiceImpl userService, ReportServiceImpl reportService) {
        super();
        setDisplay(display);
        setPrvScreen(prvScreen);
        setTitle(title);
        setLogonListner(logonListner);
        setUserService(userService);
        setReportService(reportService);

        calendarUtil = new CalenderUtil(new Date(), this.getWidth(), this.getHeight());
        calendarUtil.intializeCalender();

        addCommand(CommandPool.btnSelect);
        addCommand(CommandPool.btnEdit);
        addCommand(CommandPool.btnReport);
        addCommand(CommandPool.btnSetting);
        addCommand(CommandPool.btnAbout);
        addCommand(CommandPool.btnLogoutScreen);
        setCommandListener(this);

        getDisplay().setCurrent(this);
    }

    protected void paint(Graphics g) {
        g.setColor(0xffffff);
        g.fillRect(0, 0, this.getWidth(), this.getHeight());
        calendarUtil.paint(g);

    }

    protected void keyPressed(int key) {
        int keyCode = getGameAction(key);

        if (keyCode == FIRE) {
            new EnterHoursForm(getDisplay(), this, TextPool.TITLE(), getLogonListner(),
                    calendarUtil.getSelectedDay(), calendarUtil.getSelectedMonth(), calendarUtil.getSelectedYear(),
                    TextPool.EMPTY_STRING(), TextPool.EMPTY_STRING(), TextPool.EMPTY_STRING(), TextPool.EMPTY_STRING(),
                    TextPool.EMPTY_STRING(), TextPool.EMPTY_STRING(), getReportService(), 1);
        } else {
            calendarUtil.keyPressed(keyCode);
            repaint();
        }
    }

    public void commandAction(Command command, Displayable arg1) {
        if (command == CommandPool.btnLogoutScreen) {
            logoutView();
        }

        if (command == CommandPool.btnReport) {
            reportView();
        }

        if (command == CommandPool.btnSetting) {
            settingView();
        }

        if (command == CommandPool.btnSelect) {
            enterDataView();
        }
        if (command == CommandPool.btnAbout) {
            AboutView();
        }

        if (command == CommandPool.btnEdit) {
            EditView();
        }
    }

    /**
     * Displays the edit form.
     */
    private void EditView() {
        Report report = getReportService().getReport(calendarUtil.getSelectedMonth() + "-" + calendarUtil.getSelectedYear());
        int hr = 0, min = 0, mag = 0, bro = 0, book = 0, rv = 0;

        if (report != null) {
            hr = (report.getMinutes()) / 60;
            min = (report.getMinutes()) % 60;
            mag = report.getMagazines();
            bro = report.getBrochures();
            book = report.getBook();
            rv = report.getReturnVisits();
            report = null;
        }

        new EnterHoursForm(getDisplay(), this, TextPool.TITLE(), getLogonListner(),
                calendarUtil.getSelectedDay(), calendarUtil.getSelectedMonth(), calendarUtil.getSelectedYear(),
                hr + TextPool.EMPTY_STRING(), min + TextPool.EMPTY_STRING(), mag + TextPool.EMPTY_STRING(), bro +
                TextPool.EMPTY_STRING(), book + TextPool.EMPTY_STRING(), rv + TextPool.EMPTY_STRING(), getReportService(), 0);
    }

    /**
     * Displays the about view
     */
    private void AboutView() {
        new AboutForm(getDisplay(), this);
    }

    /**
     * Redirect to the form to enter report data.
     */
    private void enterDataView() {
        new EnterHoursForm(getDisplay(), this, TextPool.TITLE(), getLogonListner(),
                calendarUtil.getSelectedDay(), calendarUtil.getSelectedMonth(), calendarUtil.getSelectedYear(),
                TextPool.EMPTY_STRING(), TextPool.EMPTY_STRING(), TextPool.EMPTY_STRING(), TextPool.EMPTY_STRING(),
                TextPool.EMPTY_STRING(), TextPool.EMPTY_STRING(), getReportService(), 1);
    }

    /**
     * Report view
     */
    private void reportView() {
        Report report = getReportService().getReport(calendarUtil.getSelectedMonth() + "-" + calendarUtil.getSelectedYear());
        new MonthReportForm(getDisplay(), this, TextPool.TITLE(), getLogonListner(), calendarUtil.getSelectedMonth(),
                calendarUtil.getSelectedYear(), report);
    }

    /**
     * Setting view
     */
    private void settingView() {
        getReportService().shutDB();
        new ChangePassword(getDisplay(), this, getTitle(), getLogonListner(), getUserService(), getReportService());
    }

    /**
     * logout
     */
    private void logoutView() {
        alertMessage = new AlertMessage(getDisplay(), TextPool.TITLE(), this, this);
        alertMessage.showConfirm(TextPool.LOGOUT_CONFIRMATION_TEXT());
    }

    public void onAlertMessage(byte msg) {
        if (msg == AlertMessageListener.MSG_OK) {
            closeReportDatabase();
            getDisplay().setCurrent(getPrvScreen());
        } else if (msg == AlertMessageListener.MSG_CANCEL) {
            getDisplay().setCurrent(this);
        }
    }

    /**
     * Close databases
     */
    private void closeReportDatabase() {
        try {
            reportService.closeDB();
            reportService.cleanDbUp();
            getUserService().startDB();
            cleanUp();
        } catch (Exception ex) {
            ex.printStackTrace();
        }

    }

    private void cleanUp() {
        calendarUtil = null;
        title = TextPool.EMPTY_STRING();
        logonListner = null;
        alertMessage = null;
    }

    /**
     * @return the calendarUtil
     */
    public CalenderUtil getCalendarUtil() {
        return calendarUtil;
    }

    /**
     * @param calendarUtil
     *            the calendarUtil to set
     */
    public void setCalendarUtil(CalenderUtil calendarUtil) {
        this.calendarUtil = calendarUtil;
    }

    /**
     * @return the display
     */
    public Display getDisplay() {
        return display;
    }

    /**
     * @param display
     *            the display to set
     */
    public void setDisplay(Display display) {
        this.display = display;
    }

    /**
     * @return the prvScreen
     */
    public Displayable getPrvScreen() {
        return prvScreen;
    }

    /**
     * @param prvScreen
     *            the prvScreen to set
     */
    public void setPrvScreen(Displayable prvScreen) {
        this.prvScreen = prvScreen;
    }

    /**
     * @return the title
     */
    public String getTitle() {
        return title;
    }

    /**
     * @param title
     *            the title to set
     */
    public void setTitle(String title) {
        this.title = title;
    }

    /**
     * @return the logonListner
     */
    public LogonListner getLogonListner() {
        return logonListner;
    }

    /**
     * @param logonListner
     *            the logonListner to set
     */
    public void setLogonListner(LogonListner logonListner) {
        this.logonListner = logonListner;
    }

    /**
     * @return the loginService
     */
    public UserServiceImpl getUserService() {
        return userService;
    }

    /**
     * @param loginService the loginService to set
     */
    public void setUserService(UserServiceImpl userService) {
        this.userService = userService;
    }

    public ReportServiceImpl getReportService() {
        return reportService;
    }

    public void setReportService(ReportServiceImpl reportService) {
        this.reportService = reportService;
    }
}
